<template>
	<view class="page">
		<view class="head">
			<view class="headtext">本服务内容由人工智能整理生成，所提供的信息仅供参考。</view>
		</view>
		<view class="quick">
			<view class="quick_item" v-for="(v,i) in topList" :key="i" @click="submit(v.title)">
				<image class="q_icon" :src="v.icon" mode=""></image>
				<span>{{v.title}}</span>
			</view>
		</view>
		<view class="main">
			<image class="bg" src="/static/common/bg.png" mode="widthFix"></image>
			<view class="question">
				<view class="question_top">
					<view class="text">
						<view class="t1">Hi, 我是青白江惠企政策助手</view>
						<view class="t2">政策查询问题，我能帮您</view>
					</view>
					<image class="xm" src="/static/common/xm.png" mode=""></image>
				</view>
				<view class="question_center">
					<view class="recommend">为您推荐</view>
					<view class="list" v-for="v in displayedList" :key="v.id" @click="submit(v.title)">
						<view class="list_l">
							<image v-if="v.id==1" class="hat" src="/static/common/hot.png" mode=""></image>
							<span v-else class="num" :class="{'num2':v.id==2,'num3':v.id==3}">{{v.id}}</span>
							<span class="title">{{v.title}}</span>
						</view>
						<u-icon name="arrow-right" color="#323b4b" size="28rpx"></u-icon>
					</view>
				</view>
				<view class="expand" @click="questionOpen=!questionOpen">{{questionOpen?'收起':'查看更多'}}</view>
			</view>
		</view>

		<view v-for="(v,i) in answersList" :key="i">
			<view class="item_q" v-if="v.type=='q'">
				<view style="user-select: text;" class="text">{{v.text}}</view>
			</view>
			<view class="item_a" v-if="v.type=='a'">
				<view v-if="v.depth">
					<!-- 深度思考 -->
					<view class="think" @click="v.thinkOpne=!v.thinkOpne">
						<view class="think_l">
							<image class="lamp" src="/static/common/lamp.png" mode=""></image>
							已经深度思考
						</view>
						<u-icon v-show="v.thinkOpne" name="arrow-up" color="#2979ff" size="28rpx"></u-icon>
						<u-icon v-show="!v.thinkOpne" name="arrow-down" color="#2979ff" size="28rpx"></u-icon>
					</view>
					<view class="think_text" v-show="v.thinkOpne">
						<u-parse style="user-select: text;overflow-wrap: break-word;" :content="v.think"></u-parse>
					</view>
					<!-- 回答 -->
					<u-parse style="user-select: text;overflow-wrap: break-word;" :content="v.answer"></u-parse>
				</view>

				<view v-else>
					<u-parse style="user-select: text;overflow-wrap: break-word;" :content="v.answer"></u-parse>
				</view>
			</view>
		</view>

		<view class="footer">
			<view class="btns">
				<view class="btn" @click="talkFn">
					<image class="icon" src="/static/common/search.png" mode=""></image>
					<span>快速查询</span>
				</view>
				<view class="btn" @click="cleanFn">
					<image class="icon" src="/static/common/clean.png" mode=""></image>
					<span>清除对话</span>
				</view>
				<view class="btn" @click="clearAllTimers" v-if="loading">
					<image class="icon" src="/static/common/pause.png" mode=""></image>
					<span>停止生成</span>
				</view>
			</view>

			<view class="search">
				<u--input ref="myInput" @blur="blurInputFn" :focus="firstFocus" v-model="questionVal" v-show="showInput"
					placeholder="有政策问题随时问我..." border="none" confirm-type="send"
					@confirm="submit(questionVal)"></u--input>
				<view class="sea_t" v-if="textInput">
					<image @click="switchType" class="icon_l" src="/static/common/voice.png" mode=""></image>
					<view class="placeholder" @click="showInputFn">
						<span v-show="!showInput">{{questionVal||'有政策问题随时问我...'}}</span>
					</view>
					<image v-if="loading" class="icon_r" src="/static/common/load-8510_256.gif" mode=""></image>
					<image v-else class="icon_r" src="/static/common/up.png" mode="" @click="submit(questionVal)">
					</image>
				</view>
				<view class="sea_v" v-else>
					<image @click="switchType" class="icon_l" src="/static/common/text.png" mode=""></image>
					<view class="placeholder" @click="talkFn">长按说话</view>
				</view>
			</view>
		</view>
		<view style="height: 300rpx;"></view>
		<view class="ddd"></view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				// 顶部按钮
				topList: [],
				// 快捷列表
				quickList: [],
				questionOpen: false, //展开问题
				textInput: true, //文字输入或者语音输入
				showInput: false, //显示输入框
				questionVal: '', //输入问题文字
				firstFocus: false, //是否聚焦
				answersList: [], //对话框列表
				loading: false, //思考中
				timer: null, //加载的定时器
				timers: [], //所有生成的定时生成id
				eventSource: null
			}
		},
		computed: {
			// 计算是否展开
			displayedList() {
				return this.questionOpen ? this.quickList : this.quickList.slice(0, 3);
			},

		},
		onLoad() {
			this.getDataListFn()
		},
		methods: {
			//获取json数据推荐问答
			getDataListFn() {
				this.$api.getDataList().then(res => {
					// console.log(res, 'dataList数据');
					this.topList = res.topList
					this.quickList = res.quickList
				})
			},


			// 显示输入框
			showInputFn() {
				if (this.loading) {
					return uni.showToast({
						icon: 'none',
						title: '回答问题中...'
					})
				}
				this.showInput = true
				this.firstFocus = true
			},
			// 失去焦点
			blurInputFn() {
				this.showInput = false
				this.firstFocus = false
			},
			// 切换输入方式
			switchType() {
				if (this.loading) {
					return uni.showToast({
						icon: 'none',
						title: '回答问题中...'
					})
				}
				this.textInput = !this.textInput
			},
			// 清除对话
			cleanFn() {
				if (this.loading) {
					return uni.showToast({
						icon: 'none',
						title: '回答问题中...'
					})
				}
				this.answersList = []
			},
			// 长按说话
			talkFn() {
				uni.showToast({
					icon: 'none',
					title: '功能开发中...'
				})
			},

			// 停止生成
			clearAllTimers() {
				this.eventSource.close();
				this.loading = false; // 确保加载状态也被重置
			},
			// 提交问题
			submit(val) {
				if (this.loading) {
					return uni.showToast({
						icon: 'none',
						title: '回答问题中...'
					})
				}

				if (!val) {
					return uni.showToast({
						icon: 'none',
						title: '请输入需要咨询的问题'
					})
				}
				this.answersList.push({
					type: 'q', //是问题还是回答
					text: val, //问题文本
				})
				uni.showLoading({
					title: '加载中...',
					mask: true
				});
				this.scrollToBottom()
				this.loading = true
				this.$api.getBot({
					q: val
				}, {
					custom: {
						catch: true
					}
				}).then(res => {
					// console.log("res>>>", res);
					//判断返回类型
					if (res.data.answer_type == "text") {
						this.answersList.push({
							type: 'a', //问答题还是回答
							answer: res.data.answer, //回答文本
							depth: false, //是否是深度思考
						})
						this.scrollToBottom()
						uni.hideLoading();
						this.loading = false
					} else {
						// console.log("不是string的数据>>>", JSON.parse(res.data.answer));
						// console.log("generate_url>>>", JSON.parse(res.data.answer).generate_url);
						const answersListLength = this.answersList.length
						this.answersList.push({
							type: 'a', //问答题还是回答
							answer: '', //回答文本
							think: '', //思考文本
							depth: true, //是否是深度思考
							thinkOpne: true, //展开关闭思考
							thinkEnd: true, //思考结束 可以关闭思考 但是只执行一次
						})
						this.scrollToBottom()


						this.loading = true
						this.eventSource = new EventSource(JSON.parse(res.data.answer).generate_url);

						this.eventSource.onmessage = (event) => {
							const chunk = event.data;
							// 2. 提取并拼接内容
							try {
								const data = chunk ? JSON.parse(chunk) : '';
								if (data.content) {
									// 解码Unicode转义字符（如 \u003c -> <）
									let brData = data.content.replaceAll("\n",
										"</br>")
									const decodedContent = this.unescapeUnicode(
										brData);
									let fullContent = this.splitNData(decodedContent)
									// console.log("fullContent>>>", fullContent);

									// 更新页面内容（响应式渲染）
									this.$set(this.answersList[answersListLength],
										'think', fullContent[0])
									this.$set(this.answersList[answersListLength],
										'answer', fullContent[1])
									uni.$u.throttle(this.scrollToBottom, 1500)

									// 思考结束可以关闭思考
									if (this.answersList[answersListLength].thinkEnd && this.answersList[
											answersListLength].answer) {
										this.answersList[answersListLength].thinkOpne = false
										this.answersList[answersListLength].thinkEnd = false
									}
								}
								uni.hideLoading();
							} catch (e) {
								// console.error('解析JSON失败:', e);
								this.scrollToBottom()
								uni.hideLoading();
								this.loading = false
							}

						};

						this.eventSource.onerror = () => {
							// console.error("SSE 错误");
							this.eventSource.close();
							uni.hideLoading();
							this.scrollToBottom()
							this.loading = false

						};
					}
				}).catch(err => {
					this.errFn()
				})
			},
			/**
			 * 分割字符串：
			 * 1. 提取 'n' 开头到 '/n' 之前的部分
			 * 2. 提取 '/n' 之后的部分
			 * @param {string} str 输入字符串
			 * @returns {string[]} 分割后的数组
			 */
			splitNData(str) {
				const thinkRegex = /<think>(.*?)<\/think>(.*)/;
				const match = str.match(thinkRegex);

				if (match) {
					// 有</think>的情况
					return [match[1], match[2]];
				} else {
					// 没有</think>的情况
					const startIndex = str.indexOf('<think>');
					if (startIndex !== -1) {
						return [str.slice(startIndex + 7)]; // 7是'<think>'的长度
					}
					return ['', '']; // 没有<think>标签的情况
				}
			},


			// 编码转译
			unescapeUnicode(str) {
				return str.replace(/\\u([0-9a-fA-F]{4})/g, (_, code) =>
					String.fromCharCode(parseInt(code, 16))
				);
			},
			// 请求失败
			errFn() {
				uni.showToast({
					icon: 'none',
					title: '网络错误,请稍后重试!'
				})
				this.answersList.push({
					type: 'a',
					text: '网络错误,请稍后重试!'
				})
				uni.hideLoading();
				this.scrollToBottom()
				this.loading = false
			},



			// 去底部
			scrollToBottom() {
				this.questionVal = ''
				setTimeout(() => {
					uni.pageScrollTo({
						selector: ".ddd",
					});
				})
			},
		}
	}
</script>

<style lang="scss" scoped>
	.page {
		padding: 120rpx 32rpx 0;
		box-sizing: border-box;

		.head {
			background-color: #fff;
			width: 100%;
			position: fixed;
			top: 0rpx;
			left: 0;
			z-index: 999;
			display: flex;
			align-items: center;
			justify-content: center;
			padding: 20rpx 0;

			.headtext {
				width: 686rpx;
				border: 1rpx solid rgba(42, 80, 232, .3);
				border-radius: 10rpx;
				font-size: 24rpx;
				text-align: center;
				line-height: 60rpx;
			}
		}

		.quick {
			width: 100%;
			display: grid;
			grid-template-columns: repeat(3, 1fr);
			/* 3列，每列等宽 */
			gap: 30rpx;
			/* 可选：设置项目间距 */

			.quick_item {
				display: flex;
				align-items: center;
				justify-content: center;
				gap: 10rpx;
				padding: 20rpx;
				background-color: #fff;
				box-shadow: 10rpx 10rpx 20rpx rgba(0, 0, 0, 0.3);
				border-radius: 15rpx;

				.q_icon {
					width: 30rpx;
					height: 30rpx;
				}
			}
		}

		.main {
			.bg {
				width: 500rpx;
			}

			.question {
				width: 100%;
				background: linear-gradient(139deg, #e9f4ff, #cee8ff 30%, #e3f1ff, #f5faff);
				box-shadow: 0 0 19px rgba(218, 221, 222, .2);
				border-radius: 30rpx;

				.question_top {
					padding: 28rpx 28rpx 0;
					box-sizing: border-box;
					position: relative;

					.text {
						.t1 {
							font-size: 24rpx;
							color: #4e5d78;
							font-weight: 400;
						}

						.t2 {
							font-size: 36rpx;
							color: #323b4b;
							font-weight: 700;
							margin-top: 10rpx;
						}
					}

					.xm {
						width: 204rpx;
						height: 248rpx;
						position: absolute;
						right: 10rpx;
						top: -120rpx;
					}
				}

				.question_center {
					background: linear-gradient(167deg, rgba(255, 255, 255, .7), rgba(250, 242, 255, 0));
					padding: 28rpx;
					box-sizing: border-box;

					.recommend {
						color: rgb(42, 80, 232);
						font-size: 28rpx;
						font-weight: 700;
						display: inline-block;
						padding-bottom: 6rpx;
						border-bottom: 6rpx solid rgb(42, 80, 232);
					}

					.list {
						display: flex;
						align-items: center;
						justify-content: space-between;
						padding: 16rpx 10rpx;
						box-sizing: border-box;
						background: rgba(255, 255, 255, .5);
						border-radius: 5rpx;
						margin-top: 16rpx;

						.list_l {
							display: flex;
							align-items: center;
							gap: 6rpx;

							.hat {
								width: 24rpx;
								height: 24rpx;
							}

							.num {
								color: rgb(0, 0, 0);
								font-size: 28rpx;
							}

							.num2 {
								color: #ff8d1a;
							}

							.num3 {
								color: #ffc300;
							}

							.title {
								font-size: 24rpx;
								color: rgba(0, 0, 0, 0.9);
								font-weight: 400;
							}
						}
					}
				}

				.expand {
					text-align: center;
					font-size: 24rpx;
					font-weight: 400;
					color: #909bb0;
					padding-bottom: 20rpx;
				}
			}
		}

		.item_q {
			display: flex;
			justify-content: flex-end;
			margin-top: 30rpx;


			.text {
				background: #256dff;
				border-radius: 10rpx 0 10rpx 10rpx;
				padding: 10rpx;
				box-sizing: border-box;
				color: #fff;
				max-width: 90%;
				font-size: 28rpx;
			}
		}

		.item_a {
			margin-top: 30rpx;
			max-width: 90%;
			font-size: 28rpx;
			display: inline-block;
			border: 1rpx solid #eee;
			padding: 10rpx;
			box-sizing: border-box;
			border-radius: 0rpx 10rpx 10rpx 10rpx;

			.think {
				width: 100%;
				padding: 20rpx;
				box-sizing: border-box;
				background-color: #f7f7f7;
				font-size: 26rpx;
				color: rgba(0, 0, 0, .6);
				display: flex;
				align-items: center;
				justify-content: space-between;

				.think_l {
					display: flex;
					align-items: center;
					gap: 8rpx;

					.lamp {
						width: 30rpx;
						height: 30rpx;
					}
				}
			}

			.think_text {
				width: 100%;
				padding: 30rpx;
				box-sizing: border-box;
				background-color: #f7f7f7;
				font-size: 24rpx;
				color: rgba(0, 0, 0, .6);
			}

		}

		.footer {
			position: fixed;
			z-index: 100;
			bottom: 0;
			left: 0;
			background-color: #fff;
			border-top: 1rpx solid #eee;
			width: 100%;
			padding: 28rpx;
			box-sizing: border-box;

			.btns {
				display: flex;
				align-items: center;
				gap: 14rpx;

				.btn {
					display: flex;
					align-items: center;
					padding: 10rpx;
					box-sizing: border-box;
					font-size: 26rpx;
					font-weight: 700;
					box-shadow: 0 0 .03125rem rgba(0, 0, 0, .14);
					border-radius: 10rpx;
					border: 1rpx solid #e5e5e5;

					.icon {
						width: 30rpx;
						height: 30rpx;
					}
				}
			}

			.search {
				border: 1rpx solid #0D52FF;
				border-radius: 20rpx;
				padding: 20rpx;
				box-sizing: border-box;
				margin-top: 20rpx;

				.sea_t {
					display: flex;
					align-items: center;
					justify-content: space-between;
					gap: 10rpx;

					.icon_l {
						width: 50rpx;
						height: 50rpx;
					}

					.placeholder {
						flex: 1;
						color: #c6d8fe;
						font-size: 28rpx;
					}

					.icon_r {
						width: 50rpx;
						height: 50rpx;
					}
				}

				.sea_v {
					display: flex;
					align-items: center;
					gap: 10rpx;

					.icon_l {
						width: 50rpx;
						height: 50rpx;
					}

					.placeholder {
						flex: 1;
						text-align: center;
						font-size: 28rpx;
						color: #666;
					}
				}
			}
		}
	}
</style>